package main

import (
	"bytes"
	"flag"
	"fmt"
	"image"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"
)

var loading chan int8
var makePathLock chan int8
var getMovieCh chan int8
var maxLoadingNum = 20
var loadList []string
var picSpiderClient = &http.Client{}
var logFile *os.File

//"bitrate": 300,
//"src": "https://cc3001.dmm.co.jp/litevideo/freepv/1/1sd/1sdam048/1sdam048_sm_w.mp4"
//}, {
//"bitrate": 1000,
//"src": "https://cc3001.dmm.co.jp/litevideo/freepv/1/1sd/1sdam048/1sdam048_dm_w.mp4"
//}, {
//"bitrate": 1500,
//"src": "https://cc3001.dmm.co.jp/litevideo/freepv/1/1sd/1sdam048/1sdam048_dmb_w.mp4"
//}, {
//"bitrate": 3000,
//"src": "https://cc3001.dmm.co.jp/litevideo/freepv/1/1sd/1sdam048/1sdam048_mhb_w.mp4"

//test: "https://cc3001.dmm.co.jp/litevideo/freepv/s/sco/scop00718/scop00718_mhb_w.mp4"

func main() {
	log.SetFlags(log.Lshortfile | log.LstdFlags)
	logName := time.Now().Format("2006-01-02")
	logFile, _ = os.OpenFile("./log/"+logName+".log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) // 打开日志文件，不存在则创建
	log.SetOutput(logFile)

	loading = make(chan int8, maxLoadingNum)
	makePathLock = make(chan int8, 1)
	getMovieCh = make(chan int8, 2)

	newHttpClient()

	//-- picture
	go handleDownload()

	//-- movies
	moviesGeter()
	//FixMoviesActress()
	//getMissActress()

	//-- fix
	//fixFiledImg()
	//fixSuffix()
	//fixFourDir()

	log.Println("All Run Finished")
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh
}

func moviesGeter() {
	mDB.getInsertMovieStmt()
	daily := time.Now().YearDay()

	re := false
	flag.BoolVar(&re, "r", false, "refresh now")
	flag.Parse()
	if re {
		daily -= 1
	}

	var today, hour int
	var preGet = true
	// DMM
	for {
		today = time.Now().YearDay()
		hour = time.Now().Hour()

		if daily != today && hour > 3 {
			logName := time.Now().Format("2006-01-02")
			newLogFile, _ := os.OpenFile("./log/"+logName+".log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) // 打开日志文件，不存在则创建
			log.SetOutput(newLogFile)
			logFile.Close()
			logFile = newLogFile

			// 获取每日更新
			PreGetDailyMovies(30)
			// 更新演员
			getActresses()
			// 更新影片分类
			getGenre() //getGenres()
			// 更新制片
			getMakers() //getNewMaker() //getMakers()
			// 更新系列
			getSeries(5)
			daily = today
			preGet = false
		}

		// 获取电影详情
		if GetAllMoviesDetail() {
			continue
		}

		if !preGet {
			// 获取演员电影
			PreGetActorMovies()
			// 获取制片电影
			PreGetMakerMovies()
			// 获取系列电影
			PreGetSeriesMovies()
			preGet = true
		}

		time.Sleep(180 * time.Second)

		// 获取素人电影

		// 获取素人电影详情
	}
}

func fixShortCid() {
	id := 0
	for id < 69670 {
		ll := mDB.GetShortCid(id)
		for _, v := range ll {
			if _, r := strconv.Atoi(v[len(v)-4 : len(v)-3]); r != nil {
				mDB.UptMovieFilled(4, v)
				log.Println("cid is short ---", v)
			}
		}
		id += 1000
	}
}

func fixFourDir() {
	dir, err := ioutil.ReadDir("./dmm/movies")
	if err != nil {
		log.Println(err)
		return
	}

	for _, fi := range dir {
		fn := fi.Name()
		if len(fn) < 4 {
			continue
		}
		if n := strings.Index(fn, "con"); n == 0 {
			continue
		}

		d1 := "./dmm/movies/" + fn + "/"
		d2 := "./dmm/movies/" + fn[:3] + "/"

		nDir, err := ioutil.ReadDir(d1)
		if err != nil {
			log.Println(err)
			continue
		}

		if len(nDir) == 0 {
			os.Remove(d1)
		} else {
			for _, fb := range nDir {
				if mvs, _ := ioutil.ReadDir(d2 + fb.Name()); len(mvs) <= 0 {
					os.Remove(d2 + fb.Name())
				}
				log.Println(d1+fb.Name(), "->", d2+fb.Name())
				err := os.Rename(d1+fb.Name(), d2+fb.Name())
				if err != nil {
					log.Println(err)
				}
			}
			os.Remove(d1)
		}
	}
	log.Println("finished")
}

// 添加下载任务
func addDownload(mark, path, url string) {
	mDB.AddPicDown(mark, path, url)
}

// 删除文件
func delFile(file string) {
	del := os.Remove(file)
	if del != nil {
		log.Println(del)
	}
}

func foo() {
	fmt.Scanln()
}

// 协程池，channel满的时候会阻塞
func handleDownload() {
	//var s, n int
	//flag.IntVar(&s, "s", 5, "refresh now")
	//flag.IntVar(&n, "n", 20, "refresh now")
	//flag.Parse()

	//go func() {
	//	ticker := time.NewTicker(time.Second * time.Duration(s))
	//	for {
	//		select {
	//		case <-ticker.C:
	//			if len(loadList) > 0 {
	//				log.Println("--Clear loading")
	//				for li := n; li > 0; li-- {
	//					<-loading
	//				}
	//			}
	//		}
	//	}
	//}()

	for {
		if len(loadList) > 0 {
			s := loadList[0]
			l := strings.Split(s, "|")
			loadList = loadList[1:]
			loading <- 1
			go download(l[0], l[1], l[2], "", false)
			time.Sleep(500 * time.Millisecond)
		} else {
			time.Sleep(18 * time.Second)
			log.Println("--GetWillingDown")
			ll := mDB.GetWillingDown(500)
			if len(ll) > 0 {
				log.Println("load list len", len(ll))
				loadList = append(loadList, ll...)
			} else {
				time.Sleep(180 * time.Second)
			}
		}
	}
}

// 下载图片
func download(id, path, url, fName string, useProxy bool) {
	log.Println("Down Image", url)
	request, err := http.NewRequest("GET", url, nil)

	request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
	request.Header.Add("Accept-Language", "zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2")
	request.Header.Add("Connection", "keep-alive")
	request.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")

	var imgResponse *http.Response
	if useProxy {
		imgResponse, err = httpClient.Do(request)
	} else {
		imgResponse, err = picSpiderClient.Do(request)
	}

	if err != nil {
		log.Println("DownERR->", err)
		if useProxy {
			<-loading
		} else {
			download(id, path, url, fName, true)
		}
		return
	}

	defer imgResponse.Body.Close()
	imgByte, _ := ioutil.ReadAll(imgResponse.Body)

	if imgResponse.StatusCode != 200 {
		log.Println("DownERR->", imgResponse.Status)
		downErrHandle(path, url)
		<-loading
		return
	}

	n := strings.LastIndex(url, "/")
	if fName == "" {
		fName = string(url[n:])
	}
	fn := path + fName

	id8, _ := strconv.Atoi(id)
	buf := new(bytes.Buffer)
	buf.Write(imgByte)

	imgSize := len(imgByte)
	if imgSize <= 2800 {
		if n := strings.Index(url, "jp-"); n != -1 {
			url = strings.Replace(url, "jp-", "-", 1)
			log.Println("Small Img, Reload !", fName)
			time.Sleep(waitTime)
			download(id, path, url, fName, useProxy)
			mDB.UpdatePicDown(id8, 1)
			return
		}
	}

	hasGif := strings.Index(fName, ".gif")
	isNoImage := strings.Index(fName, "noimage")

	if _, _, err = image.Decode(buf); hasGif == -1 && isNoImage == -1 && err != nil {
		log.Println(err, fName)
		<-loading
		return
	}

	makePathLock <- 1
	makePath(path)
	<-makePathLock

	_, fErr := os.Stat(fn)
	var fh *os.File
	if fErr != nil {
		os.Remove(fn)
	}
	fh, _ = os.Create(fn)
	defer fh.Close()

	if _, err = fh.Write(imgByte); err == nil {
		log.Print(" | DownSUCC->", fName, "-", imgSize, " proxy:", useProxy)

		mDB.UpdatePicDown(id8, 0)
	} else {
		log.Print(" | DownFail->", fName, "-", err)
	}

	<-loading
}

// 递归文件夹
func makePath(path string) {
	pInfo, pErr := os.Stat(path)
	if pErr != nil || pInfo.IsDir() == false {
		if n := strings.LastIndex(strings.Trim(path, "/"), "/"); n > 1 {
			makePath(path[:n])
		}
		errDir := os.Mkdir(path, os.ModePerm)
		if errDir != nil {
			log.Println(errDir)
			os.Exit(-1)
		}
	}
}

// 下载失败补救
func downErrHandle(path, url string) {
	log.Println("downErrHandle:", path, url)
	//if n := strings.Index(url, ".mp4"); n == -1 {
	//	return
	//}
	//
	//if n := strings.Index(url, "101.110.118.26"); n != -1 {
	//	return
	//}
	//
	//url = url[:7] + "101.110.118.26/" + url[7:]
	//addDownload(path, url)
}

func downVideo() {

}
